<template>
<div :class="[$style.container]">

  <div :class="[$style.header]">
    <div :class="[$style.logo]">
      <el-avatar :size="32" src="/logo.png"></el-avatar>
      <span class="ml-3 text-heading ft-24">玖钉文档系统</span>
    </div>
    <div>
      <el-button type="primary" size="small" @click="onHome">前往文档系统</el-button>
    </div>
  </div>

  <div :class="[$style.body]">
    <div :class="[$style.toolbar]">
      <doc-nav :data="pageData" :doc-id="docParentId" :row="data"></doc-nav>
    </div>
    <div :class="[$style.content]">
      <ul :class="[$style.list]"
        v-infinite-scroll="onLoad"
        :infinite-scroll-disabled="disabled"
        :infinite-scroll-immediate="false" v-if="pageData.rows.length > 0">
        <li :class="[$style.item, selectCls(row), checkedCls(row)]" v-for="(row) in pageData.rows" :key="row.id"
          @dblclick="onOpen(row)"
          @click.exact="onSelect(row)">
          <div :class="[$style.col, $style.col0]" @click.stop="">
            <el-checkbox v-model="row.checked"></el-checkbox>
          </div>
          <div :class="[$style.col, $style.col1]">
            <div :class="[$style.docIcon]"><doc-icon :data="row"></doc-icon></div>
            <div :class="[$style.docContent]">
              <div :class="[$style.docText]">
                <span :underline="false" @click="onOpen(row)" :class="[$style.docTextContent]">{{row.name}}</span>
              </div>
            </div>
          </div>
          <div :class="[$style.col, $style.col2]">
            <span>{{row.modifiedTime}}</span>
            <el-divider direction="vertical" />
            <span>{{row.modifiedByName}}</span>
          </div>
          <div :class="[$style.col, $style.col3]">{{row.size | size}}</div>
          <div :class="[$style.col, $style.col4]" @click.stop="">
            <el-dropdown trigger="click">
              <span><el-link :underline="false"><i class="el-icon-more"></i></el-link></span>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item @click.native="onPreview(row)" v-if="canPreview(row)">预览</el-dropdown-item>
                <el-dropdown-item @click.native="onDownload(row)" v-if="canDownload(row)">下载</el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
          </div>
        </li>
      </ul>
      <p class="text-center text-secondary" v-if="pageData.loading">加载中...</p>
      <p class="text-center text-secondary" v-if="!pageData.hasMore && !pageData.loading && pageData.rows.length > 0">没有更多了</p>
    </div>
    <empty-data v-if="!pageData.loading && pageData.rows.length < 1">
      <div class="mb-3">没有任何文档</div>
    </empty-data>
  </div>
</div>
</template>

<script lang="ts">

import { PageData, PageQueryParams } from '@/config/page'
import { Vue, Component, Provide, Watch, Ref, Prop, Inject } from 'vue-property-decorator'
import { downloadDoc, downloadDocWithPackage, queryDocsByLink } from '@/api/doc-share'
import DocNav from './doc-nav/index.vue'
import { hasPerm } from '@/config/acl'
import { canPreview } from '@/config/content-type'
import { downloadFromBlob, downloadFromUrl } from '@/utils/download'
import { queryString } from '@/utils/url'

const sameRow = (r1: any, r2: any) => {
  return r1 === r2 || (!!r1?.id && r1?.id === r2?.id)
}

@Component({
  components: { DocNav }
})
export default class DocList extends Vue {
  @Prop() data!: any

  @Prop() accessCode!: string

  @Prop() docParentId!: string

  pageData: PageData<any> = null as any

  selectedRow: any = null

  get checkedRows () {
    return this.pageData.rows.filter(v => v.checked)
  }

  get disabled () {
    return this.pageData.loading || !this.pageData.hasMore
  }

  checkedCls (row: any) {
    return row.checked ? this.$style.checked : ''
  }

  selectCls (row: any) {
    return sameRow(row, this.selectedRow) ? this.$style.selected : ''
  }

  canDownload (row: any) {
    return this.data?.allowDownload && hasPerm('download', row)
  }

  canPreview (row: any) {
    return this.data?.allowPreview && row.type === 'file' && hasPerm('preview', row) && canPreview(row.name)
  }

  onOpen (row: any) {
    if (row.type === 'dir') {
      this.$router.push({ path: `/s/${this.data?.id}`, query: { accessCode: this.accessCode, docParentId: row.id } })
    } else {
      if (this.canPreview(row)) {
        this.onPreview(row)
      }
    }
  }

  @Provide() openUp (row: any) {
    const docParentId = row.id === this.data?.docId ? undefined : row.parentId
    this.$router.push({ path: `/s/${this.data?.id}`, query: { accessCode: this.accessCode, docParentId } })
  }

  onPreview (row: any) {
    const accessCode = this.accessCode
    const docParentId = this.docParentId
    const docId = row.id
    const query = { accessCode, docParentId, docId }
    window.open(`/s/p/${this.data?.id}?${queryString(query)}`)
  }

  onDownload (row: any) {
    if (row.type === 'file') {
      downloadDoc(this.data?.id, row.id, this.accessCode).then(url => {
        const response = {
          'content-disposition': `attachment; filename=${encodeURIComponent(row.name)}`
        }
        this.$oss.signatureUrl(url, { response }).then(url => {
          downloadFromUrl(url)
        })
      })
    } else {
      const handler = this.$message({
        showClose: true,
        message: '正在生成压缩包 ... ',
        type: 'info',
        duration: 0
      })
      downloadDocWithPackage(this.data?.id, [row.id], this.accessCode).then((response: any) => {
        const name = decodeURIComponent((response.headers['content-disposition'] || '').replace('attachment;filename=', ''))
        downloadFromBlob(response.data, name)
      }).finally(() => {
        if (handler) handler.close()
      })
    }
  }

  onSelect (row: any) {
    this.selectedRow = row || null
  }

  onHome () {
    this.$router.push('/')
  }

  onLoad () {
    this.pageData.loadNext()
  }

  created () {
    const loader = (params: PageQueryParams) => {
      const extra: any = Object.assign({ docParentId: this.docParentId, accessCode: this.accessCode }, params)
      return queryDocsByLink(this.data.id, extra).then(data => {
        data.content.forEach((w: any) => {
          w.checked = false
        })
        return data
      })
    }
    this.pageData = new PageData(loader, { size: 30 })

    this.pageData.load()
  }

  @Watch('docParentId') docParentIdChange () {
    this.pageData.load()
  }

  $style!: any
}
</script>

<style lang="scss" module>
@import "~@/styles/vars.scss";

$header-height: 40px;

$col4-width: 36px;

.container {
  height: 100vh;
  background-color: $bg-body-color;
}

.header {
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  background-color: #fff;
}

.logo {
  display: flex;
  align-items: center;
}

.body {
  background-color: #fff;
  margin: 20px 48px;
  border-radius: 4px;
}

.toolbar {
  padding: 0 20px;
  height: $header-height;
  background-color: $bg-color;
  border-bottom: 1px solid $border-split-color;
  box-sizing: border-box;
}

.content {
  height: calc(100vh - #{$header-height} - 48px - 48px);
  overflow: auto;
}

.list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.item {
  position: relative;
  display: flex;
  align-items: center;
  margin: 0 12px;
  border-bottom: 1px solid $border-split-color;
  height: 48px;
  padding: 8px 0;

  &:hover, &.checked, &.selected {
    background-color: $bg-body-color;
  }

  &:hover, &.selected {
    .actions {
      display: block;
    }
  }

  &:hover, &.checked {
    .col0 {
      visibility: visible;
    }
  }

  &.disabled {
    opacity: .6;
    cursor: not-allowed;
  }
}

.col {
  flex: 0 0 auto;
}

.col0 {
  width: 40px;
  padding-left: 8px;
  // background-color: cyan;
  visibility: hidden;
}

.col1 {
  width: 60%;
  min-width: 220px;
  flex: 1 1 auto;
  display: flex;
  // background-color: chartreuse;
}

.col2 {
  width: 15%;
  min-width: 220px;
  // background-color: chocolate;
}

.col3 {
  width: 10%;
  min-width: 60px;
  // background-color: cornflowerblue;
}

.col4 {
  width: $col4-width;
  padding-right: 12px;
  // background-color: cyan;
  text-align: right;
}

.docIcon {
  flex: 0 0 auto;
  width: 48px;
  color: $color-primary;
  font-size: 32px;
}

.docContent {
  flex: 1 1 auto;
  width: 0;
}

.docText {
  display: flex;
  align-items: center;
  width: 100%;
  margin: 12px 0;
}

.docTextContent {
  flex: 0 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;

  &:hover {
    color: $color-primary;
    opacity: .8;
    cursor: pointer;
  }
}

.docTextAction {
  flex: 0 0 auto;
}

</style>
